package com.platform.common.util.file;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.log4j.Logger;

/**
 * ftp操作文件上传、下载，注意：ftp上传文件使，文件名不能有中文
 * 
 * @author wangsh
 * 
 */
public class FTPUtil {

	private static Logger log = Logger.getLogger(FTPUtil.class);

	/**
	 * 上传文件（可供Action/Controller层使用）
	 * 
	 * @param hostname
	 *            FTP服务器地址
	 * @param port
	 *            FTP服务器端口号
	 * @param username
	 *            FTP登录帐号
	 * @param password
	 *            FTP登录密码
	 * @param pathname
	 *            FTP服务器保存目录
	 * @param fileName
	 *            上传到FTP服务器后的文件名称
	 * @param inputStream
	 *            输入文件流
	 * @return
	 */
	public static boolean uploadFile(String hostname, int port, String username, String password, String pathname,
			String fileName, InputStream inputStream) {
		boolean flag = false;
		FTPClient ftpClient = new FTPClient();
		ftpClient.setControlEncoding("UTF-8");
		try {
			// 连接FTP服务器
			ftpClient.connect(hostname, port);
			// 登录FTP服务器
			ftpClient.login(username, password);
			ftpClient.sendCommand("OPTS UTF8", "ON");
			// 是否成功登录FTP服务器
			int replyCode = ftpClient.getReplyCode();
			if (!FTPReply.isPositiveCompletion(replyCode)) {
				return flag;
			}

			ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
			ftpClient.makeDirectory(pathname);
			ftpClient.changeWorkingDirectory(pathname);
			ftpClient.storeFile(fileName, inputStream);
			inputStream.close();
			ftpClient.logout();
			flag = true;
		} catch (Exception e) {
			log.error("FTP发生异常:", e);
		} finally {
			if (ftpClient.isConnected()) {
				try {
					ftpClient.disconnect();
				} catch (IOException e) {
					log.error("FTP发生异常:", e);
				}
			}
		}
		return flag;
	}

	/**
	 * 上传文件（可对文件进行重命名）
	 * 
	 * @param hostname
	 *            FTP服务器地址
	 * @param port
	 *            FTP服务器端口号
	 * @param username
	 *            FTP登录帐号
	 * @param password
	 *            FTP登录密码
	 * @param pathname
	 *            FTP服务器保存目录
	 * @param filename
	 *            上传到FTP服务器后的文件名称
	 * @param originfilename
	 *            待上传文件的名称（绝对地址）
	 * @return
	 */
	public static boolean uploadFileFromProduction(String hostname, int port, String username, String password,
			String pathname, String filename, String originfilename) {
		boolean flag = false;
		try {
			InputStream inputStream = new FileInputStream(new File(originfilename));
			flag = uploadFile(hostname, port, username, password, pathname, filename, inputStream);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return flag;
	}

	/**
	 * 上传文件（不可以进行文件的重命名操作）
	 * 
	 * @param hostname
	 *            FTP服务器地址
	 * @param port
	 *            FTP服务器端口号
	 * @param username
	 *            FTP登录帐号
	 * @param password
	 *            FTP登录密码
	 * @param pathname
	 *            FTP服务器保存目录
	 * @param originfilename
	 *            待上传文件的名称（绝对地址）
	 * @return
	 */
	public static boolean uploadFileFromProduction(String hostname, int port, String username, String password,
			String pathname, String originfilename) {
		boolean flag = false;
		try {
			String fileName = new File(originfilename).getName();
			InputStream inputStream = new FileInputStream(new File(originfilename));
			flag = uploadFile(hostname, port, username, password, pathname, fileName, inputStream);
		} catch (Exception e) {
			log.error("FTP发生异常:", e);
		}
		return flag;
	}

	/**
	 * 删除文件
	 * 
	 * @param hostname
	 *            FTP服务器地址
	 * @param port
	 *            FTP服务器端口号
	 * @param username
	 *            FTP登录帐号
	 * @param password
	 *            FTP登录密码
	 * @param pathname
	 *            FTP服务器保存目录
	 * @param filename
	 *            要删除的文件名称
	 * @return
	 */
	public static boolean deleteFile(String hostname, int port, String username, String password, String pathname,
			String filename) {
		boolean flag = false;
		FTPClient ftpClient = new FTPClient();
		ftpClient.setControlEncoding("UTF-8");
		try {
			// 连接FTP服务器
			ftpClient.connect(hostname, port);
			// 登录FTP服务器
			ftpClient.login(username, password);
			ftpClient.sendCommand("OPTS UTF8", "ON");
			// 验证FTP服务器是否登录成功
			int replyCode = ftpClient.getReplyCode();
			if (!FTPReply.isPositiveCompletion(replyCode)) {
				return flag;
			}
			// 切换FTP目录
			ftpClient.changeWorkingDirectory(pathname.trim());
			ftpClient.dele(filename);
			ftpClient.logout();
			flag = true;
		} catch (Exception e) {
			log.error("FTP发生异常:", e);
		} finally {
			if (ftpClient.isConnected()) {
				try {
					ftpClient.disconnect();
				} catch (IOException e) {
					log.error("FTP发生异常:", e);
				}
			}
		}
		return flag;
	}

	/**
	 * 下载文件
	 * 
	 * @param hostname
	 *            FTP服务器地址
	 * @param port
	 *            FTP服务器端口号
	 * @param username
	 *            FTP登录帐号
	 * @param password
	 *            FTP登录密码
	 * @param pathname
	 *            FTP服务器文件目录
	 * @param filename
	 *            文件名称
	 * @param localpath
	 *            下载后的文件路径
	 * @return
	 */
	public static boolean downloadFile(String hostname, int port, String username, String password, String pathname,
			String filename, String localpath) {
		boolean flag = false;
		FTPClient ftpClient = new FTPClient();
		ftpClient.setControlEncoding("UTF-8");
		try {
			// 连接FTP服务器
			ftpClient.connect(hostname, port);
			// 登录FTP服务器
			ftpClient.login(username, password);
			ftpClient.sendCommand("OPTS UTF8", "ON");
			// 验证FTP服务器是否登录成功
			int replyCode = ftpClient.getReplyCode();
			if (!FTPReply.isPositiveCompletion(replyCode)) {
				return flag;
			}
			// 设置读取方式为二进制流
			ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
			// 切换FTP目录
			ftpClient.changeWorkingDirectory(pathname.trim());
			FTPFile[] ftpFiles = ftpClient.listFiles();
			for (FTPFile file : ftpFiles) {
				if (filename.equalsIgnoreCase(file.getName())) {
					File localFile = new File(localpath.trim() + File.separator + file.getName());
					OutputStream os = new FileOutputStream(localFile);
					ftpClient.retrieveFile(file.getName(), os);
					os.flush();
					os.close();
				}
			}
			ftpClient.logout();
			flag = true;
		} catch (Exception e) {
			log.error("FTP发生异常:", e);
		} finally {
			if (ftpClient.isConnected()) {
				try {
					ftpClient.disconnect();
				} catch (IOException e) {
					log.error("FTP发生异常:", e);
				}
			}
		}
		return flag;
	}

	/**
	 * 下载文件并删除源文件
	 * 
	 * @param hostname
	 *            FTP服务器地址
	 * @param port
	 *            FTP服务器端口号
	 * @param username
	 *            FTP登录帐号
	 * @param password
	 *            FTP登录密码
	 * @param pathname
	 *            FTP服务器文件目录
	 * @param filename
	 *            文件名称（模糊匹配字符串）
	 * @param localpath
	 *            下载后的文件路径
	 * @return
	 */
	public static boolean downloadFileAndDel(String hostname, int port, String username, String password,
			String pathname, String filename, String localpath) {
		boolean flag = false;
		FTPClient ftpClient = new FTPClient();
		ftpClient.setControlEncoding("UTF-8");
		try {
			// 连接FTP服务器
			ftpClient.connect(hostname, port);
			// 登录FTP服务器
			ftpClient.login(username, password);
			ftpClient.sendCommand("OPTS UTF8", "ON");
			// 验证FTP服务器是否登录成功
			int replyCode = ftpClient.getReplyCode();
			if (!FTPReply.isPositiveCompletion(replyCode)) {
				log.error("FTP连接失败,请检查配置是否正确!!");
				return flag;
			}
			// 设置读取方式为二进制流
			ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
			// 切换FTP目录
			ftpClient.changeWorkingDirectory(pathname.trim());
			// 告知ftp来开通端口传输数据,如果不写这个,可能会导致阻塞
			ftpClient.enterLocalPassiveMode();
			FTPFile[] ftpFiles = ftpClient.listFiles();
			for (FTPFile file : ftpFiles) {
				if (file.getName().toLowerCase().contains(filename.toLowerCase())) {
					log.info("读取到的文件为:" + file.getName() + "文件大小为:" + file.getSize());
					File file2 = new File(localpath.trim());
					// 文件夹不存在自动创建
					if (!file2.exists()) {
						file2.mkdirs();
					}
					File localFile = new File(localpath.trim() + File.separator + file.getName());
					OutputStream os = new FileOutputStream(localFile);
					ftpClient.retrieveFile(file.getName(), os);
					os.flush();
					os.close();
					ftpClient.dele(file.getName());
				}
			}
			ftpClient.logout();
			flag = true;
		} catch (Exception e) {
			log.error("FTP发生异常:", e);
		} finally {
			if (!ftpClient.isConnected()) {
				try {
					ftpClient.disconnect();
				} catch (IOException e) {
					log.error("FTP发生异常:", e);
				}
			}
		}
		return flag;
	}

	/**
	 * 下载文件并删除源文件(多种格式文件)
	 * 
	 * @param hostname
	 *            FTP服务器地址
	 * @param port
	 *            FTP服务器端口号
	 * @param username
	 *            FTP登录帐号
	 * @param password
	 *            FTP登录密码
	 * @param pathname
	 *            FTP服务器文件目录
	 * @param filename
	 *            文件名称（模糊匹配字符串）(可指定多个格式文件,以空格隔开)
	 * @param localpath
	 *            下载后的文件路径
	 * @return
	 * @throws IOException
	 */
	public static boolean downloadFilesAndDel(String hostname, int port, String username, String password,
			String pathname, String filenames, String localpath) throws IOException {
		boolean flag = false;
		FTPClient ftpClient = new FTPClient();
		ftpClient.setControlEncoding("UTF-8");
		try {
			// 连接FTP服务器
			ftpClient.connect(hostname, port);
			// 登录FTP服务器
			ftpClient.login(username, password);
			ftpClient.sendCommand("OPTS UTF8", "ON");
			// 验证FTP服务器是否登录成功
			int replyCode = ftpClient.getReplyCode();
			if (!FTPReply.isPositiveCompletion(replyCode)) {
				log.error("ftp连接失败,请检查ftp用户名密码或连接设置是否正确!!");
				return flag;
			}
			log.debug("ftp连接成功!!!" + "读取路径为:" + pathname.trim() + "写入路径为:" + localpath);
			// 设置读取方式为二进制流
			ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);

			// 切换FTP目录
			boolean change = ftpClient.changeWorkingDirectory(pathname.trim());
			if (change) {
				log.debug("------------------切换路径成功!!------------------");
			} else {
				change = ftpClient.changeWorkingDirectory(pathname.trim().substring(1));
				if (!change) {
					log.error("------------------切换路径失败!!------------------");
					return flag;
				}
			}
			// 告知ftp来开通端口传输数据,如果不写这个,可能会导致阻塞
			ftpClient.enterLocalPassiveMode();
			FTPFile[] ftpFiles = ftpClient.listFiles();
			String[] fileNames = filenames.trim().split("\\s+");
			for (FTPFile file : ftpFiles) {
				log.debug("开始扫描ftp上的文件----------" + file.getName());
				try {
					for (String filename : fileNames) {
						if (file.getName().toLowerCase().contains(filename.toLowerCase())) {
							log.debug("读取到的文件为:" + file.getName() + "文件大小为:" + file.getSize());
							File file2 = new File(localpath.trim());
							// 文件夹不存在自动创建
							if (!file2.exists()) {
								file2.mkdirs();
							}
							File localFile = new File(localpath.trim() + File.separator + file.getName());
							OutputStream os = new FileOutputStream(localFile);
							ftpClient.retrieveFile(file.getName(), os);
							os.flush();
							os.close();
							ftpClient.dele(file.getName());
						}
					}
				} catch (Exception e) {
					log.error("扫描" + file.getName() + "文件发生异常", e);
				}
			}
			ftpClient.logout();
			flag = true;
		} catch (Exception e) {
			log.error("FTP发生异常:", e);
		} finally {
			if (ftpClient.isConnected()) {
				try {
					ftpClient.disconnect();
				} catch (IOException e) {
					log.error("FTP发生异常:", e);
				}
			}
		}
		return flag;
	}

}